package srzy.socket

import scala.actors.Actor
import scala.actors.Actor._
import scala.actors.TIMEOUT
import java.net.SocketTimeoutException
import srzy.common.Logging
import srzy.common.Config
import srzy.diameter._
import srzy.rb._
import srzy.common.Common
import srzy.module.CaseDealContext

class RBMsgTransitActor(trend: Symbol, socketConn1: srzy.socket.RBSocketConn, socketConn2: srzy.socket.RBSocketConn)
  extends Actor with Logging {

  override def act = {
    while (true) {
      try {
        val msg = socketConn1.read
        getMsgType(msg) match {
          case CODE_KAR => {
            //            logger.debug("heartbeat rece :" + msg)
            socketConn1.replyHeartbeat
          }
          case CODE_ECA | CODE_ECR => {
            logger.error("authentication rece : " + msg)
          }
          case i: Int => {
            logger.debug("trend : " + trend + " , service type : " + i)
            //            if (CaseDealContext )
            val sid = srzy.rb.getSessionId(msg)
            if (!sid.contains(CaseDealContext.sessionId) || CaseDealContext.sessionId == "") {
              logger.error("msg:" + msg)
              logger.error("sid:" + sid)
              logger.error("trend:" + trend)
            } else {
              RBMsgQueue().offer((trend, msg))

              if (trend == 'RBToSM) {
                logger.debug("RBMsgActionQueue():" + RBMsgActionQueue())
                val v = RBMsgActionQueue().poll()
                logger.debug("v:" + v)
                if (v != null) {
                  v match {
                    case e: RBMsgSleepAction =>
                      logger.debug("rb thread sleep : " + e.time)
                      logger.debug("msg:" + msg)
                      Thread.sleep(e.time)
                      socketConn2.write(msg)
                    case e: RBMsgSleepAndDiscardAction =>
                      logger.debug("rb thread sleep and discard : " + e.time)
                      logger.debug("msg:" + msg)
                      Thread.sleep(e.time)
                    case _ =>
                      logger.error("RBMsgAction illegal")
                  }
                } else {
                  socketConn2.write(msg)
                }
              } else {
                socketConn2.write(msg)
              }
            }
          }
        }
      } catch {
        case ste: SocketTimeoutException =>
      }
    }
  }

  override def exceptionHandler = {
    case ioe: java.io.IOException => {
      logger.error(ioe.getMessage(), ioe)
      ExceptionHandle.rbSocketExceptionDeal(trend)
    }
    case e: Exception => logger.error(e.getMessage(), e)
  }

}

object RBMsgTransitActor extends Logging {

  val serverPort = Integer.parseInt(Config.getValue("root", "config", "RB_Server_Port"))

  val rbssc = new RBSocketServerConn {
    val serverSocket = try {
      SocketServerConn.create(serverPort)
    } catch {
      case e: Exception => ExceptionHandle.RBServerCreateExceptionDeal
    }
  }

  def getServerSocket = try {
    rbssc.accept
  } catch {
    case ex: Exception =>
      logger.error("Server accept error !", ex)
      ExceptionHandle.RBServerAcceptExceptionDeal
  }

  def getRBSocketConn = new RBSocketConn {
    val socket = getServerSocket
    val outStream = socket.getOutputStream()
    val inStream = socket.getInputStream()
  }

  var smSideSocketConn: RBSocketConn = getRBSocketConn

  smSideSocketConn.serverAuthentication

  val clientPort = Integer.parseInt(Config.getValue("root", "config", "RB_Port"))
  val clientIP = Config.getValue("root", "config", "RB_IP")

  def getClientSocket = try {
    SocketConn.connect(clientIP, clientPort)
  } catch {
    case ex: Exception =>
      logger.error("Client create error !", ex)
      ExceptionHandle.RBServerClientCreateExceptionDeal
  }

  val rbSideSocketConn: RBSocketConn = new RBSocketConn {
    val socket = getClientSocket
    val outStream = socket.getOutputStream()
    val inStream = socket.getInputStream()
  }

  rbSideSocketConn.clientAuthentication

  val smToRBActor = new RBMsgTransitActor('SMToRB, smSideSocketConn, rbSideSocketConn)
  val rbToSMActor = new RBMsgTransitActor('RBToSM, rbSideSocketConn, smSideSocketConn)
  smToRBActor.start
  rbToSMActor.start

}